package com.tiny.tinyweb.core.ldap.query;

import java.util.List;

import javax.naming.Name;

import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.LdapContextSource;

import com.tiny.tinyweb.core.utils.LdapUtils;

/**
 * 基于 {@link org.springframework.ldap.core.LdapTemplate}
 * 的 LDAP 操作类，提供复杂的查询操作。
 * @see {@link org.springframework.ldap.core.LdapTemplate}
 * @author wxiaobin
 */
public abstract class LdapQuery {
    /**
     * LDAP 操作模版对象。
     */
    private LdapTemplate ldapTemplate;

    /**
     * 设置 LDAP 操作模版对象。
     * @return odmManager LDAP 操作模版对象的新值
     */
    public void setLdapTemplate(LdapTemplate ldapTemplate) {
        this.ldapTemplate = ldapTemplate;
    }

    /**
     * 将目录查询结果映射到 {@link java.util.Map} 对象的
     * {@link org.springframework.ldap.core.ContextMapper}
     * 对象，该映射器将每个条目的所有属性保存在一个 {@link java.util.Map}
     * 对象中，无论多值属性还是单值属性，都用 {@link java.util.List} 保存。
     * @see {@link org.springframework.ldap.core.ContextMapper}
     */
    private final MapMapper mapMapper = new MapMapper();

    /**
     * 查询指定 DN 下满足查询条件的所有条目。
     * @param base 要查询的DN，可以为 <code>null</code>，此时基于根 DN 进行查询
     * @param filter 过滤器
     * @return 指定 DN 下满足查询条件的所有条目
     */
    public List<?> ldapRead(final String base, final String filter) {
        return this.ldapTemplate.search(
                this.buildDn(base), filter, this.mapMapper);
    }

    /**
     * 根据指定的 DN 字符串，创建不含根 DN 的
     * {@link org.springframework.ldap.core.DistinguishedName} 对象。
     * @param fullDn 指定的 DN 字符串，可以不指定 （空值或空字符串），此时返回根 DN 对象
     * @return 不含根 DN 的 DN 对象
     */
    private Name buildDn(final String fullDn) {
        return LdapUtils.buildDn(fullDn,
                ((LdapContextSource) this.ldapTemplate
                        .getContextSource()).getBaseLdapPath());
    }
}
